package com.flashidea.zddziot.activity;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Calendar;
import java.util.TimeZone;

import com.flashidea.zddziot.ContentValues;
import com.flashidea.zddziot.R;
import com.flashidea.zddziot.utlis.BluetoothChatService;
import com.flashidea.zddziot.utlis.CMDUtils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification.Action;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

/**
 * This is the main Activity that displays the current chat session.
 */
public abstract class BluetoothChatActivity extends Activity {
	// Debugging
	private static final String TAG = "BluetoothChat";
	protected static final boolean D = ContentValues.D;

	// BluetoothChatService Handler处理的信息类型
	public static final int MESSAGE_STATE_CHANGE = 1;
	public static final int MESSAGE_READ = 2;
	public static final int MESSAGE_WRITE = 3;
	public static final int MESSAGE_DEVICE_NAME = 4;
	public static final int MESSAGE_TOAST = 5;

	// Key names received from the BluetoothChatService Handler
	public static final String KEY_DEVICE_NAME = "device_name";
	public static final String KEY_TOAST = "toast";
	public static final String KEY_TOAST_ID = "toast_id";

	// Intent request codes
	private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
	protected static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
	private static final int REQUEST_ENABLE_BT = 3;
	
	// 广播action
	public static final String ACTION_BLUETOOTH_STATE_CHANGE = "com.flashidea.zddziot.activity.BluetoothChatActivity.BLUETOOTH_STATE_CHANGE";
	public static final String ACTION_AFTER_WRITE_MESSAGE = "com.flashidea.zddziot.activity.BluetoothChatActivity.AFTER_WRITE_MESSAGE";
	public static final String ACTION_READ_MESSAGE = "com.flashidea.zddziot.activity.BluetoothChatActivity.READ_MESSAGE";
	public static final String ACTION_DEVICE_NAME_CHANGE = "com.flashidea.zddziot.activity.BluetoothChatActivity.DEVICE_NAME_CHANGE";

	//广播Intent Extra
	public static final String EXTRA_BLUETOOTH_STATE = "bluetooth_state";
	public static final String EXTRA_WRITE_MESSAGE = "write_message";
	public static final String EXTRA_READ_MESSAGE = "read_message";
	public static final String EXTRA_DEVICE_NAME = "device_name";

	// Local Bluetooth adapter
	private BluetoothAdapter mBluetoothAdapter = null;
	// Member object for the chat services
	protected BluetoothChatService mChatService = null;
	//当前连接的设备名
	private String mConnectedDeviceName;

	public String getmConnectedDeviceName() {
		return mConnectedDeviceName;
	}

	//发送|接受的字符编码
	private String encoding = null;
	
	private String mAddress;
	private SharedPreferences sp;
	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (D)
			Log.e(TAG, "+++ ON CREATE +++");
		sp = getSharedPreferences(MainActivity.PREF_CONFIG, Context.MODE_PRIVATE);
		// Get local Bluetooth adapter
		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

		// If the adapter is null, then Bluetooth is not supported
		if (mBluetoothAdapter == null) {
			Toast.makeText(this, getResources().getString(R.string.bluetooth_not_available),
					Toast.LENGTH_SHORT).show();
			if (D)
				Log.e(TAG, "Bluetooth is not available");
			finish();
			return;
		}
	}

	@SuppressLint("NewApi")
	@Override
	protected void onStart() {
		super.onStart();
		if (D)
			Log.e(TAG, "++ ON START ++");

		// 如果蓝牙处于关闭状态，申请开启蓝牙
		// setupChat()方法将在onActivityResult被调用
		if (!mBluetoothAdapter.isEnabled()) {
			Intent enableIntent = new Intent(
					BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
			// Otherwise, setup the chat session
		} else {
			if (mChatService == null)
				setupChat();
		}
	}

	protected void initChatService() {
		// Performing this check in onResume() covers the case in which BT was
		// not enabled during onStart(), so we were paused to enable it...
		// onResume() will be called when ACTION_REQUEST_ENABLE activity
		// returns.
		if (mChatService != null) {
			// Only if the state is STATE_NONE, do we know that we haven't
			// started already
			if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
				// Start the Bluetooth chat services
				mChatService.start();
				
				//检测是否有未正常断开的连接
				String connected_device = sp.getString(MainActivity.CONNECTING_DEVICE, null);
				if(!TextUtils.isEmpty(connected_device)){
					connectDevice(connected_device,false);
				}
				
			}
			Log.i(TAG, "------ SYNC ------");
			//发送机器同步命令
			sendMessage(CMDUtils.SYNC);
		}
	}

	@SuppressLint("NewApi")
	private void setupChat() {
		Log.d(TAG, "setupChat()");

		// Initialize the BluetoothChatService to perform bluetooth connections
		mChatService = BluetoothChatService.getInstance(this, mHandler);
		
		initView();
		
		//注册相关广播
		registerBroadcastReceivers();
		
		initChatService();
		
		
	}
	/**
	 * 初始化控件 
	 * 在Activity onStar()方法中调用（蓝牙开启后）
	 */
	protected abstract void initView();
	@Override
	protected void onPause() {
		super.onPause();
		if (D)
			Log.e(TAG, "- ON PAUSE -");
	}

	@Override
	protected void onStop() {
		super.onStop();
		if (D)
			Log.e(TAG, "-- ON STOP --");
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (D)
			Log.e(TAG, "--- ON DESTROY ---");
//		if(mChatService != null){
//			Log.e(TAG, "you must call stopBluetoothChat() method on onDestroy() method！");  
//		}
		//关闭所有广播接收者
		unRegisterBroadcastReceivers();
	}
	
	/**
	 * 停止蓝牙服务<br/>
	 * <i>必须在应用关闭前执行</i>
	 * 
	 */
	protected void stopBluetoothChat() {
		if (mChatService != null)
			mChatService.stop();
	}
	/**
	 * 设置设备可见
	 */
	@SuppressLint("NewApi")
	protected void ensureDiscoverable() {
		if (D)
			Log.d(TAG, "ensure discoverable");
		if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
			Intent discoverableIntent = new Intent(
					BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
			discoverableIntent.putExtra(
					BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
			startActivity(discoverableIntent);
		}
	}

	/**
	 * 发送消息
	 * 
	 * @param message
	 *            A string of text to send.
	 */
	protected void sendMessage(String message) {
		// Check that we're actually connected before trying anything
		if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
			onBluetoothChatStateChange(mChatService.getState());
			return;
		}
		Log.i(TAG, "sendMessage : " + message);
		// Check that there's actually something to send
		if (message.length() > 0) {
			// Get the message bytes and tell the BluetoothChatService to write
			byte[] send = message.getBytes();
			mChatService.write(send);
		}
	}

	/**
	 * 在发送信息之后
	 * @param writeMessage
	 * @see {@link sendMessage(String message)}
	 */
	protected abstract void onAfterWriteMessage(String writeMessage);
	/**
	 * 当蓝牙服务状态发送改变
	 * @param state 
	 * 			代表当前状态<br/>
	 * {@link BluetoothChatService.STATE_CONNECTED} : 已连接<br/>
	 * {@link BluetoothChatService.STATE_CONNECTING} : 正在连接<br/>
	 * {@link BluetoothChatService.STATE_LISTEN} : 等后信息中<br/>
	 * {@link BluetoothChatService.STATE_NONE} : 什么也没做<br/>
	 */
	protected void onBluetoothChatStateChange(int state) {
		switch (state) {
		case BluetoothChatService.STATE_CONNECTED:
			Toast.makeText(this,
					getResources().getString(R.string.connection_successful),
					Toast.LENGTH_SHORT).show();
			//发送同步码
			sendMessage(CMDUtils.SYNC);
			break;
		case BluetoothChatService.STATE_CONNECTING:
			Toast.makeText(this,
					getResources().getString(R.string.title_connecting),
					Toast.LENGTH_SHORT).show();
			break;
		case BluetoothChatService.STATE_LISTEN:
		case BluetoothChatService.STATE_NONE:
			Toast.makeText(this,
					getResources().getString(R.string.connection_lost),
					Toast.LENGTH_SHORT).show();
			break;
		default:
			break;
		}
	}

	/**
	 * 保存连接的设备到配置文件
	 */
	private void saveConnDevice() {
		Log.d("saveConnDevice", "save mAddress : " + mAddress);
		sp.edit().putString(MainActivity.CONNECTING_DEVICE,mAddress).commit();
	}

	/**
	 * 当连接的设备改变后
	 * @param mConnectedDeviceName2
	 */
	protected abstract void onConnectedDeviceNameChange(String mConnectedDeviceName2);

	/**
	 * 当接收到蓝牙设备的信息
	 * @param readMessage
	 */
	protected abstract void onReadMessage(String readMessage);

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (D)
			Log.d(TAG, "onActivityResult " + resultCode);
		switch (requestCode) {
			case REQUEST_CONNECT_DEVICE_SECURE :
				// When DeviceListActivity returns with a device to connect
				if (resultCode == Activity.RESULT_OK) {
					connectDevice(data, true);
				}
				break;
			case REQUEST_CONNECT_DEVICE_INSECURE :
				// When DeviceListActivity returns with a device to connect
				if (resultCode == Activity.RESULT_OK) {
					connectDevice(data, false);
				}
				break;
			case REQUEST_ENABLE_BT :
				// When the request to enable Bluetooth returns
				if (resultCode == Activity.RESULT_OK) {
					// Bluetooth is now enabled, so set up a chat session
					setupChat();
					Log.d(TAG, "BT enabled");
					Toast.makeText(this, getResources().getString(R.string.bluetooth_available), Toast.LENGTH_SHORT).show();
				} else {
					// User did not enable Bluetooth or an error occured
					Log.d(TAG, "BT not enabled");
					Toast.makeText(this, getResources().getString(R.string.bluetooth_not_available), Toast.LENGTH_SHORT).show();
					finish();
				}
		}
	}
	/**
	 * 连接列表选中的蓝牙设备
	 * 
	 * @param data
	 * @param secure
	 */
	@SuppressLint({"NewApi", "NewApi"})
	private void connectDevice(Intent data, boolean secure) {
		String address = data.getExtras().getString(
				DeviceListActivity.EXTRA_DEVICE_ADDRESS);
		connectDevice(address, secure);
	}
	
	private void connectDevice(String Address, boolean secure) {
		mAddress = Address;
		saveConnDevice();
		// Get the BLuetoothDevice object
		BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mAddress);
		// Attempt to connect to the device
		mChatService.connect(device, secure);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
//		MenuInflater inflater = getMenuInflater();
//		inflater.inflate(R.menu.option_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
//		switch (item.getItemId()) {
//			case R.id.secure_connect_scan : // 建立安全的连接
//				startDeviceListActivity(REQUEST_CONNECT_DEVICE_INSECURE);
//				return true;
//			case R.id.open_system_setting :// 进入手机中的蓝牙设置界面
//				startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
//				return true;
//			/*case R.id.discoverable : // 让设备可见
//				// Ensure this device is discoverable by others
//				ensureDiscoverable();
//				return true;*/
//		}
		return false;
	}

	protected void startDeviceListActivity(int requestCode) {
		Intent serverIntent = new Intent(this, DeviceListActivity.class);
		startActivityForResult(serverIntent,
				requestCode);
	}

	public String getEncoding() {
		return encoding;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}
	
	
	// The Handler that gets information back from the BluetoothChatService
	private Handler mHandler = new Handler() {
	
			@Override
			public void handleMessage(Message msg) {
				Intent intent;
				switch (msg.what) {
					case MESSAGE_STATE_CHANGE :
						if (D)
							Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
						int state = msg.arg1;
						
						intent = new Intent(ACTION_BLUETOOTH_STATE_CHANGE);
						intent.putExtra(EXTRA_BLUETOOTH_STATE, state);
						sendBroadcast(intent);
						break;
					case MESSAGE_WRITE :
						byte[] writeBuf = (byte[]) msg.obj;
						// construct a string from the buffer
						String writeMessage;
						if(!TextUtils.isEmpty(encoding)){
							try {
								writeMessage = new String(writeBuf,encoding);
							} catch (UnsupportedEncodingException e) {
								if(D) Log.e(TAG, "error encoding!!");
								writeMessage = new String(writeBuf);//使用默认编码
							}
						}else{
							writeMessage = new String(writeBuf);//使用默认编码
						}
						
						if(D)Log.i(TAG, "handleMessage : AFTER_MESSAGE_WRITE : " +writeMessage);
						intent = new Intent(ACTION_AFTER_WRITE_MESSAGE);
						intent.putExtra(EXTRA_WRITE_MESSAGE, writeMessage);
						sendBroadcast(intent);
						break;
					case MESSAGE_READ :
						
						//AT#2112*   //正常情况
						//AT#2112*AT#656*  //两个完整命令连在一起    AT#2112   AT#656*
						//AT#2112*AT#656  //两个命令连在一起  但最后的那个不完整 
						//AT#2112AT#656*  //两个命令连在一起  但前面的那个不完整
						//2112AT#656  //两个命令连在一起  两个都不完整
						try {
							byte[] readBuf = (byte[]) msg.obj;
							//长度
							int len = msg.arg1;
							printByteArr(readBuf,len);
							String readMessage;
							readMessage = new String(readBuf, 0, len, ContentValues.ENDCODING); 
							if(D) Log.i(TAG, " readMessage : " + readMessage);
							int endIndex = -1;
							String substring;
							String[] split = readMessage.split(CMDUtils.COMMON_HEAD);
							for (String string : split) {
								endIndex = string.indexOf(CMDUtils.END_CHART);
								if(endIndex > -1){
									substring = CMDUtils.COMMON_HEAD + string.substring(0, endIndex);
									if(D)Log.i(TAG," substring : " + substring);
//									if(substring.startsWith(CMDUtils.MUSIC_NAME_HEAD)){ //歌名信息
//										substring = getMusicName(substring, CMDUtils.getMusicEncoding(readMessage));
//									}
									sendReadMessageBroadcast(substring);
								}
							}
						} catch (Exception e) {
							e.printStackTrace();
							if(D) Log.e(TAG, "split readMessage error!!" + e.toString());
						}
						
						break;
					case MESSAGE_DEVICE_NAME :
						// save the connected device's name
						mConnectedDeviceName = msg.getData().getString(KEY_DEVICE_NAME);
						
						intent = new Intent(ACTION_DEVICE_NAME_CHANGE);
						intent.putExtra(EXTRA_DEVICE_NAME, mConnectedDeviceName);
						sendBroadcast(intent);
						break;
					case MESSAGE_TOAST :
						int id = msg.getData().getInt(KEY_TOAST_ID);
						if(id > 0){
							Toast.makeText(getApplicationContext(),
									getResources().getString(id), Toast.LENGTH_SHORT)
									.show();
						}else{
							Toast.makeText(getApplicationContext(),
									msg.getData().getString(KEY_TOAST), Toast.LENGTH_SHORT)
									.show();
						}
						break;
				}
			}

			private void printByteArr(byte[] readBuf, int len) {
				StringBuffer sb = new StringBuffer();
				sb.append("[");
				for (int i = 0; i < len; i++) {
					sb.append(readBuf[i]);
					if(i == len -1){
						sb.append("]");
					}else{
						sb.append(", ");
					}
					
				}
				if(D) Log.i(TAG, " >>> " + sb.toString());
			}
			
		};
		/**
		 * 将用GBK编码解码后显示乱码的字符串重新用正确的编码去解码
		 * @param nameCMD AT#22Uxxx.mp3   (使用GBK编码后的字符串)
		 * @param encoding 正确的编码
		 * @return
		 * @throws Exception
		 */
		protected String getMusicName(String nameCMD , String encoding) throws Exception {
			byte[] cmdBytes = nameCMD.getBytes(ContentValues.ENDCODING); //重新通过GBK将字符串转成字节数组
			//截取歌名部分字节数组         去掉头  AT#21U -- 6个字节  
			byte[] nameBytes = Arrays.copyOfRange(cmdBytes, 6, cmdBytes.length); 
			byte temp ; 
			if("UNICODE".equalsIgnoreCase(encoding)){
				if(nameBytes.length % 2 != 0){ //是否是双数的长度
					//如果是单数的话  在后面加多一个字节0
					nameBytes = Arrays.copyOf(nameBytes, nameBytes.length + 1);
				}
				for (int i = 0; i < nameBytes.length - 1; i = i+2) {
					temp = nameBytes[i];
					nameBytes[i] = nameBytes[i + 1];
					nameBytes[i + 1] = temp;
				}
			}else if("GBK".equalsIgnoreCase(encoding)){
				//GBK无需转换
			}else{
				throw new Exception("错误的编码!"); 
			}
			return new String(nameBytes,encoding);
		}
		
	private synchronized void sendReadMessageBroadcast(String readMessage) {
		Intent intent;
		intent = new Intent(ACTION_READ_MESSAGE);
		intent.putExtra(EXTRA_READ_MESSAGE, readMessage);
		sendBroadcast(intent);
	}
	//
	class DeviceNameChangeBroadcast extends BroadcastReceiver{
		@Override
		public void onReceive(Context context, Intent intent) {
			if(ACTION_DEVICE_NAME_CHANGE.equals(intent.getAction())){
				onConnectedDeviceNameChange(intent.getStringExtra(EXTRA_DEVICE_NAME));
				saveConnDevice();
			}
		}
	}
	
	//
	class ReadMessageBroadcast extends BroadcastReceiver{
		@Override
		public void onReceive(Context context, Intent intent) {
			if(ACTION_READ_MESSAGE.equals(intent.getAction())){
				if(D) Log.i(TAG, " ReadMessageBroadcast : " + intent.getStringExtra(EXTRA_READ_MESSAGE));
				onReadMessage(intent.getStringExtra(EXTRA_READ_MESSAGE));
			}
		}
	}
	
	class AfterWriterMessageBroadcast extends BroadcastReceiver{
		@Override
		public void onReceive(Context context, Intent intent) {
			if(ACTION_AFTER_WRITE_MESSAGE.equals(intent.getAction())){
				if(D) Log.i(TAG, " AfterWriterMessageBroadcast : " + intent.getStringExtra(EXTRA_WRITE_MESSAGE));
				onAfterWriteMessage(intent.getStringExtra(EXTRA_WRITE_MESSAGE));
			}
		}
	}
	
	class BluetoothStateChangeBroadcast extends BroadcastReceiver{
		@Override
		public void onReceive(Context context, Intent intent) {
			if(ACTION_BLUETOOTH_STATE_CHANGE.equals(intent.getAction())){
				if(D) Log.i(TAG, " BluetoothStateChangeBroadcast : " + intent.getIntExtra(EXTRA_BLUETOOTH_STATE,-1));
				onBluetoothChatStateChange(intent.getIntExtra(EXTRA_BLUETOOTH_STATE, -1));
			}
		}
	}
	BroadcastReceiver stateChangeReceiver = null;
	BroadcastReceiver writerMessageReceiver = null;
	BroadcastReceiver readMessageReceiver = null;
	BroadcastReceiver deviceNameChangeReceiver = null;
	
	private void registerBroadcastReceivers(){
		stateChangeReceiver = new BluetoothStateChangeBroadcast();
		writerMessageReceiver = new AfterWriterMessageBroadcast();
		readMessageReceiver = new ReadMessageBroadcast();
		deviceNameChangeReceiver = new DeviceNameChangeBroadcast();
		
		registerReceiver(stateChangeReceiver, new IntentFilter(ACTION_BLUETOOTH_STATE_CHANGE));
		registerReceiver(writerMessageReceiver, new IntentFilter(ACTION_AFTER_WRITE_MESSAGE));
		registerReceiver(readMessageReceiver, new IntentFilter(ACTION_READ_MESSAGE));
		registerReceiver(deviceNameChangeReceiver, new IntentFilter(ACTION_DEVICE_NAME_CHANGE));
	}
	
	private void unRegisterBroadcastReceivers(){
		try {
			unregisterReceiver(stateChangeReceiver);
			unregisterReceiver(writerMessageReceiver);
			unregisterReceiver(readMessageReceiver);
			unregisterReceiver(deviceNameChangeReceiver);
		} catch (Exception e) {
			//广播没有被注册 或者 已经关闭广播
			Log.i(TAG, "广播没有被注册 或者 已经关闭广播");
		}
	}

}
